package com.ccovo.controller;

import cn.dev33.satoken.annotation.*;
import cn.dev33.satoken.stp.StpUtil;
import com.ccovo.domain.R;
import com.ccovo.domain.constants.Constants;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequiredArgsConstructor
@Api(tags = "注解鉴权接口")
@RequestMapping("/annotation_auth")
public class AnnotationAuthController {

    /**
     * @SaCheckLogin: 登录校验 —— 只有登录之后才能进入该方法。
     * @SaCheckRole("admin"): 角色校验 —— 必须具有指定角色标识才能进入该方法。
     * @SaCheckPermission("user:add"): 权限校验 —— 必须具有指定权限才能进入该方法。
     * @SaCheckSafe: 二级认证校验 —— 必须二级认证之后才能进入该方法。
     * @SaCheckHttpBasic: HttpBasic校验 —— 只有通过 HttpBasic 认证后才能进入该方法。
     * @SaCheckHttpDigest: HttpDigest校验 —— 只有通过 HttpDigest 认证后才能进入该方法。
     * @SaIgnore：忽略校验 —— 表示被修饰的方法或类无需进行注解鉴权和路由拦截器鉴权。
     * @SaCheckDisable("comment")：账号服务封禁校验 —— 校验当前账号指定服务是否被封禁。
     */

    /**
     * 登录校验
     */
    @ApiOperation(value = "登录校验")
    @PostMapping("/checkLogin")
    @SaCheckLogin
    public R<?> checkLogin() {
        return R.ok();
    }

    /**
     * 角色校验
     */
    @ApiOperation(value = "角色校验")
    @PostMapping("/checkRole")
    @SaCheckRole(Constants.ADMIN)
    public R<?> checkRole() {
        return R.ok();
    }

    /**
     * 权限校验
     */
    @ApiOperation(value = "权限校验")
    @PostMapping("/checkPermission")
    @SaCheckPermission("user.add")
    public R<?> checkPermission() {
        return R.ok();
    }

    /**
     * 二级认证校验
     */
    @ApiOperation(value = "二级认证校验")
    @PostMapping("/checkSafe")
    @SaCheckSafe()
    public R<?> checkSafe() {
        return R.ok();
    }

    /**
     * Http Basic 校验
     */
    @ApiOperation(value = "Http Basic 校验")
    @PostMapping("/checkHttpBasic")
    // 账号密码：sa:123456
    @SaCheckHttpBasic(account = "sa:123456")
    public R<?> checkHttpBasic() {
        return R.ok();
    }

    /**
     * Http Digest 校验
     */
    @ApiOperation(value = "Http Digest 校验")
    @PostMapping("/checkHttpDigest")
    // 账号密码：sa:123456
    @SaCheckHttpDigest(value = "sa:123456")
    public R<?> checkHttpDigest() {
        return R.ok();
    }

    /**
     * 校验当前账号是否封禁"comment"服务
     */
    @ApiOperation(value = "校验当前账号是否封禁\"comment\"服务")
    @PostMapping("/checkDisable")
    @SaCheckDisable("comment")
    public R<?> checkDisable() {
        return R.ok();
    }

    /**
     * 权限校验(OR)
     */
    @ApiOperation(value = "权限校验(OR)")
    @PostMapping("/checkPermissionOr")
    @SaCheckPermission(value = {"user.add", "user.edit"}, mode = SaMode.OR)
    public R<?> checkPermissionOr() {
        return R.ok();
    }

    /**
     * 权限校验(AND)
     */
    @ApiOperation(value = "权限校验(AND)")
    @PostMapping("/checkPermissionAnd")
    @SaCheckPermission(value = {"user.add", "user.edit"}, mode = SaMode.AND)
    public R<?> checkPermissionAnd() {
        return R.ok();
    }

    /**
     * 角色权限双重OR校验
     * orRole 字段代表权限校验未通过时的次要选择，两者只要其一校验成功即可进入请求方法，其有三种写法：
     * 写法一：orRole = "admin"，代表需要拥有角色 admin 。
     * 写法二：(OR) orRole = {"admin", "manager", "staff"}，代表具有三个角色其一即可。
     * 写法三：(AND) orRole = {"admin, manager, staff"}，代表必须同时具有三个角色。
     */
    @ApiOperation(value = "角色权限双重OR校验")
    @PostMapping("/checkPermissionOrRole")
    @SaCheckPermission(value = "user.add", orRole = Constants.ADMIN)
    public R<?> checkRoleOr() {
        return R.ok();
    }

    /**
     * 忽略认证
     * @SaIgnore 修饰方法时代表这个方法可以被游客访问，修饰类时代表这个类中的所有接口都可以游客访问。
     * @SaIgnore 具有最高优先级，当 @SaIgnore 和其它鉴权注解一起出现时，其它鉴权注解都将被忽略。
     * @SaIgnore 同样可以忽略掉 Sa-Token 拦截器中的路由鉴权
     */
    @ApiOperation(value = "忽略认证")
    @PostMapping("/ignore")
    @SaIgnore
    public R<?> ignore() {
        return R.ok();
    }

    /**
     * 批量注解鉴权
     */
    @ApiOperation(value = "批量注解鉴权")
    @PostMapping("/batch")
    @SaCheckOr(
            login = @SaCheckLogin,
            role = @SaCheckRole(Constants.ADMIN),
            permission = @SaCheckPermission("user.add"),
            safe = @SaCheckSafe("update-password"),
            httpBasic = @SaCheckHttpBasic(account = "sa:123456"),
            disable = @SaCheckDisable("submit-orders")
    )
    public R<?> batch() {
        return R.ok();
    }



}
